<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
import { Icon, Loading, Button } from 'vant'
import axios from 'axios'

interface WebBrowserProps {
  title?: string;
  url?: string;
}

const props = defineProps<WebBrowserProps>()

const emit = defineEmits(['close'])

const loading = ref(true)
const loadError = ref(false)
const errorMessage = ref('')
const iframeRef = ref<HTMLIFrameElement | null>(null)
const contentMode = ref<'iframe'|'text'|'error'>('iframe')
const textContent = ref('')
const isCheckingUrl = ref(false)
const iframeErrorType = ref<'blocked'|'network'|'security'|'unknown'>('unknown')
const proxyAvailable = ref(false)
const directMode = ref(true) // 新增：是否直接模式
const hasTried = ref(false) // 新增：是否已尝试过连接代理

// 从环境变量获取代理URL，添加详细的错误处理和日志记录
const PROXY_BASE_URL = computed(() => {
  try {
    const proxyUrl = import.meta.env.VITE_PROXY_URL || 'http://59.37.95.157:2333';
    console.log('代理服务URL:', proxyUrl);
    return proxyUrl;
  } catch (e) {
    console.error('无法读取环境变量VITE_PROXY_URL', e);
    return 'http://59.37.95.157:2333';
  }
})

// 修改为使用专门的代理服务器端点
const CLASH_PROXY_BASE_URL = computed(() => {
  try {
    const clashProxyUrl = import.meta.env.VITE_CLASH_PROXY_URL || 'http://59.37.95.157:7890';
    console.log('Clash代理URL:', clashProxyUrl);
    return clashProxyUrl;
  } catch (e) {
    console.error('无法读取环境变量VITE_CLASH_PROXY_URL', e);
    return 'http://59.37.95.157:7890';
  }
})

const handleBack = () => {
  emit('close')
}

const handleLoad = () => {
  loading.value = false
  loadError.value = false
}

const handleError = () => {
  loading.value = false
  loadError.value = true
  
  if (!errorMessage.value) {
    errorMessage.value = '网页加载失败，请尝试使用其他查看方式'
  }
  
  if (contentMode.value === 'iframe') {
    contentMode.value = 'error'
  }
}

// 修改safeUrl计算属性以使用自定义代理服务
const safeUrl = computed(() => {
  if (!props.url) return ''
  try {
    // 确保URL正确编码
    let encodedUrl = props.url;
    try {
      // 尝试解析URL，确保是有效的URL
      new URL(props.url);
    } catch (e) {
      console.error('URL解析失败，尝试编码:', e);
      encodedUrl = encodeURI(props.url);
    }
    
    // 检查代理模式
    if (directMode.value) {
      console.log('【URL处理】使用直接模式加载URL:', encodedUrl);
      return encodedUrl; // 直接模式直接返回URL
    }
    
    // 使用自定义代理服务 - 通过特殊格式构造URL
    console.log('【URL处理】使用代理模式加载URL:', encodedUrl);
    
    // 确保URL包含协议部分
    if (!encodedUrl.startsWith('http')) {
      encodedUrl = 'https://' + encodedUrl;
      console.log('【URL处理】添加协议前缀:', encodedUrl);
    }
    
    // 使用代理服务转发请求
    return `${PROXY_BASE_URL.value}/${encodedUrl}`;
  } catch (e) {
    console.error('【URL处理】URL处理错误:', e)
    return props.url || '';
  }
})

const originalUrl = computed(() => {
  if (!props.url) return ''
  try {
    return new URL(props.url).toString()
  } catch (e) {
    return ''
  }
})

const formatTitle = () => {
  if (!props.title) return '外部网站'
  if (props.title.length > 20) {
    return props.title.substring(0, 20) + '...'
  }
  return props.title
}

// 修改文本内容获取方法，使用专用代理服务获取内容
const switchToTextMode = async () => {
  if (contentMode.value === 'text') return
  
  console.log('【文本模式】切换到文本模式');
  loading.value = true
  contentMode.value = 'text'
  
  try {
    let response;
    let targetUrl = props.url || '';
    
    console.log('【文本模式】原始URL:', targetUrl);
    
    // 确保URL包含协议部分
    if (!targetUrl.startsWith('http')) {
      targetUrl = 'https://' + targetUrl;
      console.log('【文本模式】添加协议前缀:', targetUrl);
    }
    
    // 如果使用代理模式，通过代理服务访问目标URL
    if (!directMode.value && proxyAvailable.value) {
      const proxyUrl = `${PROXY_BASE_URL.value}/${targetUrl}`;
      console.log('【文本模式】使用代理URL:', proxyUrl);
      
      response = await axios.get(proxyUrl, {
        timeout: 20000,
        headers: {
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        }
      });
    } else {
      // 尝试直接访问
      console.log('【文本模式】直接访问URL:', targetUrl);
      
      try {
        response = await axios.get(targetUrl, {
          timeout: 15000,
          headers: {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
          }
        });
      } catch (directError) {
        console.error('【文本模式】直接访问失败，尝试通过代理:', directError);
        
        // 直接访问失败，尝试使用代理
        if (proxyAvailable.value) {
          const proxyUrl = `${PROXY_BASE_URL.value}/${targetUrl}`;
          console.log('【文本模式】降级使用代理URL:', proxyUrl);
          
          response = await axios.get(proxyUrl, {
            timeout: 20000,
            headers: {
              'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
            }
          });
        } else {
          throw directError;
        }
      }
    }
    
    console.log('【文本模式】内容获取成功:', response.status);
    
    // 解析HTML内容
    if (typeof response.data === 'string') {
      // 简单的HTML处理 - 移除脚本和其他可能有问题的元素
      let html = response.data;
      html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
      html = html.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, '');
      
      // 处理基础路径问题
      try {
        const baseUrl = new URL(targetUrl);
        const baseTag = `<base href="${baseUrl.origin}${baseUrl.pathname}" target="_blank">`;
        html = html.replace(/<head>/i, `<head>${baseTag}`);
        console.log('【文本模式】已添加base标签', baseUrl.origin);
      } catch (e) {
        console.error('【文本模式】处理base标签失败:', e);
      }
      
      textContent.value = html;
    } else {
      // JSON或其他格式
      textContent.value = `<pre>${JSON.stringify(response.data, null, 2)}</pre>`;
      console.log('【文本模式】返回非字符串内容，已格式化为JSON');
    }
  } catch (error: unknown) {
    console.error('【文本模式】获取内容失败:', error);
    textContent.value = '抱歉，无法获取网页内容';
    
    if (error instanceof Error) {
      errorMessage.value = error.message || '内容获取失败';
    } else if (axios.isAxiosError(error) && error.response) {
      errorMessage.value = `服务器返回错误 (${error.response.status}): ${error.response.statusText}`;
    } else {
      errorMessage.value = '内容获取失败';
    }
  } finally {
    loading.value = false;
  }
}

// 修改检查URL可访问性的方法，增加详细日志
const checkUrlEmbeddable = async () => {
  if (!props.url || isCheckingUrl.value) return;
  
  console.log('【URL检查】开始检查URL:', props.url);
  isCheckingUrl.value = true;
  directMode.value = true; // 默认使用直接模式
  
  try {
    let targetUrl = props.url;
    
    // 确保URL包含协议部分
    if (!targetUrl.startsWith('http')) {
      targetUrl = 'https://' + targetUrl;
      console.log('【URL检查】添加协议前缀:', targetUrl);
    }
    
    // 第一步：检查直接访问URL的可能性
    try {
      console.log('【URL检查】尝试直接访问:', targetUrl);
      const headResponse = await axios.head(targetUrl, { 
        timeout: 5000,
        validateStatus: () => true // 接受任何状态码
      });
      console.log('【URL检查】直接访问状态码:', headResponse.status);
      
      if (headResponse.status >= 200 && headResponse.status < 400) {
        console.log('【URL检查】直接访问成功，使用直接模式');
        directMode.value = true;
        proxyAvailable.value = true; // 标记为proxy可用，这样可以在直接模式失败时切换
      } else {
        console.log('【URL检查】直接访问返回错误状态码，尝试代理');
        await checkProxyAvailability();
      }
    } catch (directErr) {
      console.log('【URL检查】直接访问失败，尝试使用代理:', directErr);
      await checkProxyAvailability();
    }
  } catch (error) {
    console.error('【URL检查】URL检查失败:', error);
    // 默认使用直接模式，但标记代理为不可用
    directMode.value = true;
    proxyAvailable.value = false;
  } finally {
    isCheckingUrl.value = false;
    console.log('【URL检查】检查完成,模式:', directMode.value ? '直接' : '代理', '代理可用:', proxyAvailable.value);
  }
}

// 新增：检查代理可用性函数
const checkProxyAvailability = async () => {
  try {
    // 尝试通过代理服务器访问baidu作为测试
    console.log('【代理检查】开始检查代理服务可用性');
    const testUrl = 'https://www.baidu.com';
    const proxyTestUrl = `${PROXY_BASE_URL.value}/${testUrl}`;
    
    console.log('【代理检查】测试URL:', proxyTestUrl);
    const proxyResponse = await axios.head(proxyTestUrl, { 
      timeout: 8000,
      validateStatus: () => true
    });
    
    console.log('【代理检查】代理测试状态码:', proxyResponse.status);
    
    if (proxyResponse.status >= 200 && proxyResponse.status < 400) {
      console.log('【代理检查】代理服务可用，切换到代理模式');
      proxyAvailable.value = true;
      directMode.value = false; // 使用代理模式
    } else {
      console.log('【代理检查】代理服务测试返回错误状态码，使用直接模式');
      proxyAvailable.value = false;
    }
  } catch (proxyErr) {
    console.error('【代理检查】代理测试失败:', proxyErr);
    proxyAvailable.value = false;
  }
}

// 修改reload逻辑，支持模式切换和详细日志
const reloadPage = () => {
  if (!props.url) return;
  
  console.log(`【刷新页面】使用${directMode.value ? '直接' : '代理'}模式重新加载`);
  loading.value = true;
  loadError.value = false;
  errorMessage.value = '';
  contentMode.value = 'iframe';
  
  if (iframeRef.value) {
    console.log('【刷新页面】新的URL:', safeUrl.value);
    iframeRef.value.src = safeUrl.value;
    startLoadingTimeout(); // 重新开始计时
  }
}

// 添加切换访问模式的功能
const toggleAccessMode = () => {
  directMode.value = !directMode.value;
  console.log(`切换到${directMode.value ? '直接' : '代理'}模式`);
  reloadPage();
}

const openInNewTab = () => {
  if (props.url) {
    window.open(props.url, '_blank')
  }
}

// iframe加载超时处理，增加详细日志
let timeoutTimer: number | undefined = undefined;

const startLoadingTimeout = () => {
  if (timeoutTimer) {
    clearTimeout(timeoutTimer);
    console.log('【超时处理】清除现有超时定时器');
  }
  
  // 根据是否使用代理设置不同的超时时间
  const timeoutDuration = directMode.value ? 20000 : 25000; // 代理模式给更多超时时间
  console.log(`【超时处理】设置加载超时: ${timeoutDuration}ms, 模式: ${directMode.value ? '直接' : '代理'}`);
  
  timeoutTimer = window.setTimeout(() => {
    if (loading.value) {
      console.log('【超时处理】iframe加载超时');
      
      if (!hasTried.value) {
        hasTried.value = true;
        
        // 当前模式超时，尝试切换模式
        if (directMode.value && proxyAvailable.value) {
          console.log('【超时处理】直接模式超时，尝试切换到代理模式');
          directMode.value = false;
          reloadPage();
          return;
        } else if (!directMode.value) {
          console.log('【超时处理】代理模式超时，切换回直接模式');
          directMode.value = true;
          reloadPage();
          return;
        }
      }
      
      // 已尝试所有模式，仍然超时
      console.log('【超时处理】所有模式都已尝试，显示超时错误');
      handleError();
      errorMessage.value = '网页加载超时，请尝试其他方式查看';
    }
  }, timeoutDuration);
}

const handleIframeLoad = () => {
  console.log(`Iframe ${directMode.value ? '直接' : '代理'}模式加载成功`);
  loading.value = false;
  loadError.value = false;
  
  if (timeoutTimer) {
    clearTimeout(timeoutTimer);
    timeoutTimer = undefined;
  }
}

const handleIframeError = (e: Event) => {
  console.error(`Iframe ${directMode.value ? '直接' : '代理'}模式加载失败:`, e);
  
  // 如果直接模式失败且代理可用，尝试使用代理
  if (directMode.value && proxyAvailable.value) {
    console.log('直接模式加载失败，尝试切换到代理模式');
    directMode.value = false;
    reloadPage();
    return;
  }
  
  // 如果代理模式失败，尝试直接模式
  if (!directMode.value) {
    console.log('代理模式加载失败，切换到直接模式');
    directMode.value = true;
    reloadPage();
    return;
  }
  
  // 如果两种模式都失败
  if (!proxyAvailable.value) {
    errorMessage.value = '由于安全限制，无法直接加载该网页，且代理服务不可用';
  } else {
    errorMessage.value = '网页加载失败，请尝试使用其他查看方式';
  }
  
  loading.value = false;
  loadError.value = true;
  contentMode.value = 'error';
}

onMounted(() => {
  console.log('【WebBrowser】组件已挂载, URL:', props.url);
  checkUrlEmbeddable();
  startLoadingTimeout();

  // 添加无法加载iframe时的处理
  window.addEventListener('error', (e) => {
    const target = e.target as HTMLElement;
    if (target === iframeRef.value) {
      console.error('【WebBrowser】捕获到iframe加载错误事件', e);
      handleIframeError(e);
    }
  }, true);
})

onBeforeUnmount(() => {
  if (timeoutTimer) {
    clearTimeout(timeoutTimer)
  }
})
</script>

<template>
  <div class="web-browser">
    <div class="browser-header">
      <div class="back-button" @click="handleBack">
        <Icon name="arrow-left" size="20" />
      </div>
      <div class="title">{{ formatTitle() }}</div>
      <div class="browser-controls">
        <!-- 切换访问模式按钮 -->
        <div class="browser-icon" @click="toggleAccessMode" v-if="proxyAvailable">
          <Icon :name="directMode ? 'guide-o' : 'shield-o'" size="18" :color="directMode ? '#666' : '#4080ff'" />
        </div>
        <!-- 分享按钮 -->
        <div class="browser-icon" @click="openInNewTab">
          <Icon name="share-o" size="18" />
        </div>
        <!-- 切换内容模式 -->
        <div class="browser-icon" @click="contentMode === 'iframe' ? switchToTextMode() : reloadPage()">
          <Icon :name="contentMode === 'iframe' ? 'description' : 'replay'" size="18" />
        </div>
      </div>
    </div>
    
    <div class="browser-content">
      <!-- 加载中状态 -->
      <div v-if="loading" class="loading-container">
        <Loading type="spinner" color="#4080ff" size="36" />
        <span>网页加载中...</span>
        <p class="loading-tip">
          {{ directMode ? '直接加载模式' : '通过代理加载' }}
          <span v-if="!proxyAvailable" class="proxy-status">(代理不可用)</span>
        </p>
      </div>
      
      <!-- iframe嵌入模式 -->
      <iframe
        v-if="contentMode === 'iframe' && url"
        ref="iframeRef"
        :src="safeUrl"
        frameborder="0"
        @load="handleIframeLoad"
        @error="handleIframeError"
        sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
        loading="eager"
      ></iframe>
      
      <!-- 文本模式 -->
      <div v-if="contentMode === 'text'" class="text-mode-container">
        <div v-if="textContent" class="text-content" v-html="textContent"></div>
        <div v-else class="empty-message">无法获取文本内容</div>
      </div>
      
      <!-- 错误状态 - 添加更详细的错误信息和重试按钮 -->
      <div v-if="contentMode === 'error'" class="error-container">
        <Icon name="warning-o" size="48" color="#ff976a" />
        <p class="error-title">网页加载失败</p>
        <p class="error-message">{{ errorMessage }}</p>
        
        <div class="error-status">
          <Icon name="info-o" size="16" color="#909399" />
          <span>{{ directMode ? '直接模式' : '代理模式' }} {{ !proxyAvailable ? '(代理不可用)' : '' }}</span>
        </div>
        
        <div class="error-actions">
          <Button type="primary" size="small" @click="switchToTextMode">
            文本模式查看
          </Button>
          <Button 
            v-if="proxyAvailable" 
            plain 
            type="primary" 
            size="small" 
            @click="toggleAccessMode"
          >
            切换{{ directMode ? '代理' : '直接' }}模式
          </Button>
          <Button plain type="primary" size="small" @click="reloadPage">
            重新加载
          </Button>
          <Button plain type="primary" size="small" @click="openInNewTab">
            在浏览器中打开
          </Button>
        </div>
      </div>
      
      <!-- 增加模式切换提示 -->
      <div v-if="proxyAvailable" class="proxy-mode-indicator" @click="toggleAccessMode">
        <Icon :name="directMode ? 'guide-o' : 'shield-o'" size="14" :color="directMode ? '#666' : '#4080ff'" />
        <span>{{ directMode ? '直接访问' : '代理访问' }}</span>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.web-browser {
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: white;
  
  .browser-header {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid #eee;
    background-color: #f8f9fa;
    
    .back-button {
      width: 36px;
      height: 36px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
      margin-right: 12px;
      
      &:active {
        background-color: rgba(0, 0, 0, 0.05);
      }
    }
    
    .title {
      flex: 1;
      font-size: 16px;
      font-weight: 500;
      color: #333;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    
    .browser-controls {
      display: flex;
      
      .browser-icon {
        width: 36px;
        height: 36px;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 50%;
        color: #666;
        
        &:active {
          background-color: rgba(0, 0, 0, 0.05);
        }
      }
    }
  }
  
  .browser-content {
    flex: 1;
    position: relative;
    
    .loading-container {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 24px;
      background-color: #f9f9f9;
      z-index: 5;
      
      span {
        color: #666;
        font-size: 16px;
      }

      .loading-tip {
        font-size: 14px;
        color: #909399;
        margin-top: 12px;
        
        .proxy-status {
          color: #ff976a;
        }
      }
    }
    
    iframe {
      width: 100%;
      height: 100%;
      border: none;
      display: block;
    }
    
    .text-mode-container {
      height: 100%;
      overflow-y: auto;
      background-color: white;
      
      .text-content {
        font-size: 16px;
        line-height: 1.6;
        
        :deep(img) {
          max-width: 100%;
          height: auto;
        }
        
        :deep(a) {
          color: #4080ff;
          text-decoration: none;
        }
      }
      
      .empty-message {
        padding: 20px;
        text-align: center;
        color: #999;
      }
    }
    
    .error-container {
      height: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      
      .error-title {
        font-size: 18px;
        font-weight: 500;
        margin: 12px 0;
        color: #333;
      }
      
      .error-message {
        font-size: 14px;
        color: #666;
        margin-bottom: 24px;
        text-align: center;
      }

      .error-status {
        display: flex;
        align-items: center;
        gap: 6px;
        color: #909399;
        font-size: 12px;
        margin-bottom: 16px;
      }
      
      .error-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 10px;
        justify-content: center;
      }
    }
    
    .proxy-mode-indicator {
      position: absolute;
      bottom: 12px;
      right: 12px;
      padding: 6px 12px;
      background-color: rgba(255, 255, 255, 0.9);
      border-radius: 16px;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
      display: flex;
      align-items: center;
      gap: 6px;
      font-size: 12px;
      color: #666;
      z-index: 10;
      cursor: pointer;
      transition: all 0.2s;
      
      &:hover {
        background-color: rgba(255, 255, 255, 1);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
      }
    }
  }
}
</style>
